/*
 * Copyright 2010 Christoph Widulle (christoph.widulle@googlemail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */



package com.android1.amarena2d.nodes.sprites;

import com.android1.amarena2d.commons.BlendFunction;
import com.android1.amarena2d.engine.GL;
import com.android1.amarena2d.engine.Resource;
import com.android1.amarena2d.engine.SpriteBatchInstance;
import com.android1.amarena2d.engine.render.AmarenaSpriteBatch;
import com.android1.amarena2d.nodes.BaseNode;
import com.android1.amarena2d.nodes.behavior.delegates.AnimatedActionTarget;
import com.android1.amarena2d.nodes.behavior.delegates.AnimationDelegate;
import com.android1.amarena2d.nodes.behavior.delegates.SetFrameAnimationDelegate;
import com.android1.amarena2d.texture.ManagedTexture;
import com.android1.amarena2d.texture.TextureFrame;

public class SpriteBatchNode<T extends BatchedSprite> extends BaseNode<T> implements AnimatedActionTarget.SetFrame, Resource.Consumer {

    protected TextureFrame textureFrame;
    protected ManagedTexture managedTexture;

    AmarenaSpriteBatch spriteBatch;
    protected BlendFunction blendFunction = BlendFunction.DEFAULT;

    protected AnimationDelegate animationDelegate;


    public SpriteBatchNode(TextureFrame textureFrame) {
        this.textureFrame = textureFrame;
        this.managedTexture = textureFrame.getManagedTexture();
    }

    public SpriteBatchNode(ManagedTexture managedTexture) {
        this.textureFrame = managedTexture.createFullTextureFrame();
        this.managedTexture = managedTexture;
    }

    @Override
    public void init() {
        if (!init) {
            this.spriteBatch = SpriteBatchInstance.get();
            managedTexture.obtainRef(this);
            managedTexture.init();
            super.init();
        }
    }

    @Override
    public void dispose() {
        if (init) {
            managedTexture.releaseRef(this);
            managedTexture.dispose();
            super.dispose();
        }
    }

    @Override
    public void onRender() {
        GL.blendFunc(blendFunction);
        spriteBatch.begin();
    }

    @Override
    public void onRenderEnd() {

        spriteBatch.end();
        GL.invalidateColor();

    }

    public void setManagedTexture(final ManagedTexture managedTexture) {
        updateManagedTexture(managedTexture);
        setTextureFrame(managedTexture.createFullTextureFrame());

    }

    private void updateManagedTexture(final ManagedTexture managedTexture) {
        if (this.managedTexture != (managedTexture)) {
            this.managedTexture.releaseRef(this);
            this.managedTexture = managedTexture;
            this.managedTexture.obtainRef(this);
            if (running) {
                this.managedTexture.init();
            }
        }
    }
     @Override
    public void setTextureFrame(final TextureFrame textureFrame) {
        if (textureFrame.getManagedTexture() != this.managedTexture) {
            updateManagedTexture(managedTexture);
        }
        this.textureFrame = textureFrame;
        if (children != null) {
            final int size = children.size();
            if (size > 0) {
                for (int i = 0; i < size; i++) {
                    final BatchedSprite e = children.get(i);
                    if (e != null) {
                        e.setTextureFrame(textureFrame);
                    }
                }
            }
        }
    }
     @Override
    public AnimationDelegate animation() {
        if (animationDelegate == null)
            animationDelegate = new SetFrameAnimationDelegate(this);
        return animationDelegate;
    }

    @Override
    protected void attachChild(T e) {
        if (e.getTextureFrame() == null && textureFrame != null)
            e.setTextureFrame(textureFrame);
        super.attachChild(e);
    }


}